
/**
 * @fileoverview Defines namespace for 'analytics' package.
 * @link http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml
 * @link https://developers.google.com/closure/compiler/docs/js-for-compiler
 */


/**
 * Defines namespace for 'analytics' package.
 * @namespace Defines namespace for 'analytics' package.
 */
var analytics = analytics || {};



/**
 * Simple data grid.
 * @param {Element} container The data grid container.
 * @constructor
 * @static
 * @example
 * <b>var</b> data = {
 *   'columns': ['Date', 'Visits', 'Views'],
 *   'rows': [
 *     ['2013-07-24', 2, 3],
 *     ['2013-07-25', 5, 6]
 *   ],
 *   'totals': ['', 7, 9]
 * };
 * <b>var</b> options = {
 *   'table-css-class': 'grid',
 *   'column-css-prefix': 'col-'
 * };
 * <b>var</b> grid = <b>new </b>analytics.DataGrid(container);
 * grid.draw(data, options);
 */
analytics.DataGrid = function(container) {

  /**
   * Draws the data grid.
   * @param {Array.<Array>} data The data to draw.
   * @param {Object=} opt_options A optional grid configuration options.
   */
  this.draw = function(data, opt_options) {
    options_ = opt_options || options_;
    /** @type {Array.<string>} */ var columns = data['columns'] || [];
    /** @type {Array.<Array>} */ var rows = [].concat(data['rows'] || []);
    /** @type {Array.<number>} */ var totals = data['totals'] || [];

    if (!columns.length && rows) {
      columns = rows.shift();
    }

    drawColumns_(columns);
    drawRows_(rows);
    drawTotals_(totals);
  };

  /**
   * @param {Array.<string>} columns The list of table columns.
   * @private
   */
  function drawColumns_(columns) {
    /** @type {HTMLTableSectionElement} */
    var thead = createTableSection_('THEAD');
    /** @type {HTMLElement} */ var row = thead.insertRow(-1);
    for (/** @type {number} */ var i = 0; i < columns.length; i++) {
      var column = row.insertCell(-1);
      column.innerHTML = columns[i];
      column.className = (options_['column-css-prefix'] || 'col-') + i;
    }
  }

  /**
   * @param {Array.<Array>} rows The list of table rows.
   * @private
   */
  function drawRows_(rows) {
    /** @type {HTMLTableSectionElement} */
    var tbody = createTableSection_('TBODY');
    for (/** @type {number} */ var i = 0; i < rows.length; i++) {
      insertRow_(tbody, rows[i]);
    }
  }

  /**
   * @param {Array.<number>} totals The list of totals.
   * @private
   */
  function drawTotals_(totals) {
    if (totals.length) {
      /** @type {HTMLTableSectionElement} */
      var tfoot = createTableSection_('TFOOT');
      insertRow_(tfoot, totals);
    }
  }

  /**
   * @param {string} tagName The table section element name.
   * @return {HTMLTableSectionElement} Returns create table section.
   * @private
   */
  function createTableSection_(tagName) {
    /** @type {Node} */
    var section = (table_.appendChild(dom.createElement(tagName)));
    return /** @type {HTMLTableSectionElement} */ (section);
  }

  /**
   * @param {HTMLTableSectionElement} section The table section element.
   * @param {Array} values The row cells values.
   * @private
   */
  function insertRow_(section, values) {
    /** @type {HTMLElement} */ var row = section.insertRow(-1);
    for (/** @type {number} */ var i = 0; i < values.length; i++) {
      /** @type {string} */ var value = values[i];
      if (value && isDigit_(value)) value = formatter_.format(value);
      row.insertCell(-1).innerHTML = value || '';
    }
  }

  /**
   * @param {string} value The value to test.
   * @return {boolean} Returns true if value is digit, false otherwise.
   * @private
   */
  function isDigit_(value) {
    return /^\-?\d+\.?\d*$/.test('' + value);
  }

  /**
   * @private
   */
  function init_() {
    table_ = /** @type {HTMLTableElement} */
        (container.appendChild(dom.createElement('TABLE')));
    table_.className = options_['table-css-class'] || 'grid';
  }

  /**
   * @type {HTMLTableElement}
   * @private
   */
  var table_;

  /**
   * The grid configuration options.
   * @type {!Object}
   * @private
   */
  var options_ = {};

  /**
   * @type {!formatters.NumberFormatter}
   * @private
   */
  var formatter_ = new formatters.NumberFormatter;

  init_();
};
